Our app is now complete in that all of the essential functionality has been added, so in this final
project, listen will be adding platform specific application menus, shortcuts and any other finishing
touches to make our app a truly native experience over to the project code.
And first thing to take note of before we start this is that in previous versions of electronic application,
menus were commonly created from the renderer using the remote module.
You can even still see an example of this in Electron's menu documentation here.
I mentioned this as a lot of stack overflow answers and other resources will still contain this, but
it's to be avoided.
Electron is slowly getting rid of the remote module altogether.
So knowing this will create and implement our app menu directly from the main process as it's meant
to be.
To keep this a bit more modular and organized, I'll be separating all of the menu code into a new script
or local module.
So start by creating that file in the main project directory menu chase.
The script or module will export a single default function for creating the entire application menu.
So start by setting module export equal to an anonymous function in which we can perform all of the
menu logic.
To do this will need Electron's menu module requiring right at the start of the script menu from Electron
will again build the entire menu from a menu template or JavaScript object.
So in this function, start by creating that template, assigning to template an empty array for now,
both the menu from this template using the menu module we required from electron assigning to menu menu
dot build from template.
This template object and lastly set this resulting menu as the main application menu by calling menu
dot set application menu.
That's it, despite our menu being empty, when this module is required and executed, being that we
are only exporting one function, our custom application menu will be created.
We'll do this from Maine.
Yes, of course.
So over to that file.
Require the menu module assigning to a menu, require in the same directory menu, this app menu variable
now holding that function to create the menu, which we can call as soon as the main window is created
right here.
Executing app menu, save this to test everything works, and there we now have an empty app menu with
only this one item added by Mac automatically, this first item being the name of the app on Mac, something
will change in the next section.
This one default item also not containing any menu items yet.
So the next step then having our menu being built from this template is to start adding menu items in
the first menu location, add a menu item object or simply applying JavaScript object, seeing as this
is a template with a label of items.
This being the menu to control all of our apps item functionality, I'll set a submenu on this menu
item being where we'll add the sub menu items for this top level item to an empty array.
For now, this being as a menu item without some content won't be shown, will fill this with more menu
items in a minute.
Then the second top level item I'll set as the edit menu.
If you recall from the lesson on menus, this is something we can have electron handle for us by either
giving individual edit menu item roles such as copy paste, etc., or the simplest way give this entire
menu item a roll of edit menu.
This role instructs Electron to create the entire edit menu for us with operating system specific items.
Next, we can add the window menu with a similar automatic roll configuration of window menu.
And lastly, as per convention, the help menu with a roll of help.
This roll is a bit less complete and we'll add some more items to it in a minute.
But again, to have it show up in the menu, assign it an empty submenu for now.
Their note, however, that this won't work on Mac.
Now, as we've set the first menu item as a custom menu item object with the label of items and not
that required name menu item that we've already seen.
Remember, Mac always requires the first element to be the name of the app.
So to add that required item in the first position for Mac only, we'll have to check the platform the
app is running on, which we can do with if no need for the parentheses as this will be a simple one
liner process platform.
This platform property returning either Win32 or 164 for windows, depending on the specific version
of Windows Linux for any Linux operating systems or for Mac to add this first menu item, Darwan Darwin
being the original name for Apple's operating system and still forms the core of Mac OS.
OK, so when this menu is being created on Mac, we'll add that one extra menu item to the start of
the template array as it's a standard array we can just call template and shift with another roll configured
menu item of app menu.
That's it.
Electron making it very simple for us at menu like edit menu being a complete solution specifically
for that first Mac menu item.
There should now work so save.
And there we see all the new menu items with that first item, having the auto generated roll items
items itself is still empty.
For now, we have a very detailed edit menu, including all of the undo, redo and textural commands
window to manage the up windows.
We can see the dev tools window in here as well and help, which by default contains a Mac specific
search field and that empty submenu we added.
That submenu is, however, required.
So let's add a simple cross platform menu item to it.
Back in Menu Dutches in this HELP submenu array, add a new object label, learn more with a click handler
and which will simply open a URL with more information about the app.
This can be a website for your app or even a link to the App Store listing.
Just keep in mind that if you are going to launch the App Store link to your app, it's probably best
to again check the platform and link to the specific App Store for the user's operating system.
In my case, I'll simply launch the app repo on GitHub will want to launch this in the user's default
browser.
So using the shell module call in this function, shell dot open external to that GitHub URL, which
we can copy from packaged JSON.
And paste not forgetting to also require the shell module again from electron shell, save this to test.
I'll bring an empty browser window into view.
Open the help menu, click and the URL to that apropo was launched, providing the user with some more
information regarding the app.
I'll move this out the way again.
And as mentioned before, the Help menu also has that default search field, which is perfectly integrated
with our app for finding app functionality.
For example, Typing Cut shows us that a menu item with that name exists and links to several related
help articles over that menu item, which shows a pointer to where it can be found in the menu.
Very helpful.
OK, so that's essentially all of our standard menu items done next.
Then we can move on to adding our app item functionality to this Empty Items submenu.
I'll start with the existing commands like open or delete and simply make them accessible via the menu.
First item being add new.
With a click handler.
And as the name suggests, clicking this item should do the same as clicking the plus button to open
the model for adding a new item like this, but we obviously can't do that easily right from the main
processor script.
So instead we can send a simple one way IPSI message to the main app window responsible for handling
that logic or approaches, to be exact.
Remember Main Window Load's main dot html and that links to apologize, which is responsible for showing
the model.
So to message your browser window or renderer instance directly from the main process using epoxy.
We don't actually need to use the epoxy module.
Electron handles this internally for us.
We can simply call on the web contents of the browser window.
We want to message so main window dot web content, the send method.
Except that right now we don't have access to the main window in this module.
We'll have to actually pass it in as an argument when executing the module.
I'll call it up win or app window, making it the one and only argument of this module function.
And then over in mind is where we execute this set up one to be main window dot web content.
They're giving us a reference to that main app, Windows Web content.
In order to message it via IPSI, we still need to set a channel name, which is what we'll use to identify
the task for this menu show model.
No data or response is needed.
Meaning to execute this menu.
Action in the Renderer.
We can listen on this IPC Channel Nine.
I'll copy the channel name over to James EPOXI Renderer already being available open modal from menu
listening with IPSI Renderer on for that channel name menu show modal past this a callback to fire whenever
a message is received in which will simply trigger a click on the plus button element.
This one here show model dot click.
Save everything to test.
Add new now showing under the items menu click and the new item Odourless opened directly from the menu.
With this action being a menu item, we can now also very easily assign it a keyboard shortcut back
to Menu Doges set this new menu items accelerator property to command or control plus.
Oh the standard open command save.
That item now automatically showing us in the menu that it has a keyboard shortcut, press it command
being on Mac.
Oh, and the new item are shown same as clicking the button or menu item, allowing users to quickly
switch to the app, open the modal from the keyboard, paste the link and hit enter all done without
any mouse clicks and a much better experience for users inclined to do so.
The next item command then being to open an item or more specifically opened the selected item.
Keep in mind we can already navigate items with the keyboard, but at the moment we still have to double
click to actually open them.
Add that new menu item to the items submenu with a label of read item setting the accelerator immediately.
This time I'll make it command or control.
Plus enter with a click handler in which will again message the renderer process.
Same as the first item up when send.
Menu, open item.
At the listener in Ineptitudes.
Open selected item from menu.
Listening as before on.
Copy that channel name.
Menu open item in which we'll call items dot open the open command, opening the selected item by default,
save all.
I'll select the second item, no dossier's, the new item with a shortcut key is in the menu, so click
it.
And the selected item is opened in a reader window, closed this without deleting it, navigate to the
first item with the keyboard, open it with command, enter and time.
So that's all working.
Then for our third item action, we can add the ability to manually delete an item without having to
click the done button in the reader window, create another new submenu object label this delete item.
Shortcut can be command or control, plus backspace, a click handler to send the message up when send
menu delete item, copy this channel name to implement the listener.
Delete selected item from menu, same as before, ipsi renderer on menu, delete item.
With a callback, we again have this delete functionality in place with items to delete, but we need
to pass items, delete the index of the item to delete.
So in this callback function, get the selected item with items, don't get selected item.
This returns an object with the selected item element and its index.
We're only interested in the index.
So immediately after delete that selected item with items dot delete passing in the selected item index.
Selected item.
Dot index.
Test this.
I'll delete the second item by selecting it, click that new menu item delete item.
And gone at back electron G's with command Comando HTP s electron G's dot org enter.
And that's at it, so having all functionality accessible directly from the keyboard, we can now also
add extended functionality to the app via this items menu.
For example, let's allow the user to open an item in their default browser instead of a reader window
within the app.
Just a bit of flexibility again at a fourth item to this items menu labeled open in browser.
Make it short cut, a variation of the lead item command.
I'll just add an extra modifier key command or control as before, plus shift plus enter.
So the normal read item command with the addition of also holding the shift key.
Message the renderer on claque.
When dot send.
Menu, open item, as with the menu item native, I'll copy this channel name, add another listener
in Apter J.S..
Open item in native browser from menu.
Listen with IPC Renderer.
Pasting the channel name.
And in this listener's callback, we can call on the items module open native, which doesn't exist
yet.
So let's create that over two items.
James, I'll add this new function all the way down with the normal open function just makes a bit more
sense there.
Open selected item in native browser.
Declare new function, export open native equals a function in which we can start by performing the
exact first few steps, as in this open function check, we have items alse return, get the currently
selected item and get the content overall from that items you are all data attribute.
Copy this.
And faced with the last step being to open this content in the USA's default browser.
Using shell open external content quarrell, not forgetting to also require the shell module being a
shared module.
I'll jump right to the top of the script.
Const using structure assignment require shell from electron safe to test.
I'll bring that browser window from earlier over into view again.
Select the second item to open in my default browser.
Click that new item open in browser and a new Chrome tab is opened with the electronic item, you are
loaded exactly the same as in our own reader window, with the exception of being able to mark the item
as done again, just allowing the user some choice over how they use the app.
There's one last function of the app that we still cannot access via the keyboard, that being the search
field.
The default command to enter search is command s on Mac or control is on Windows and Linux.
So let's add that as the final items menu item back to menu doges, add a new submenu object.
Labeled search items.
Short cut, as mentioned, be in command or control plus s.
And a click handler sending to the app window.
Menu, focus, search, copy the channel name over to Abdul Aziz.
Focus the search input from the menu.
Listening as before for menu focus, search for a callback in which all we need to do is focus the search,
input the selector here, search, dot, focus, save both files.
We see that new item in the items menu, although it will probably never be used from there.
So press command is and the search input is focused, meaning I can just type add a new item with command
over https jams stack dot org.
Command is to search again Jamm, which now leaves only that new item clear the search, navigate to
that last item using the keyboard command center and it opened, at which point, once the user is done
with it, simply click done closing and deleting the item from the app.
So that's our app done.
Of course, there's going to be a lot of possible improvements and possibly even some minor bugs as
this was both very quickly.
But for the most part, it's an extremely well integrated desktop app.
Regardless of the operating system in the next section of the course will prepare this project for packing
and compile a distributable app using electron builder.